home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / ge_cool.lha / GE_COOL2.1 / src / Matrix / Matrix.h < prev    next >
C/C++ Source or Header  |  1992-07-01  |  14KB  |  375 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. // Copyright (C) 1992 General Electric Company.
  4. //
  5. // Permission is granted to any individual or institution to use, copy, modify,
  6. // and distribute this software, provided that this complete copyright and
  7. // permission notice is maintained, intact, in all copies and supporting
  8. // documentation.
  9. //
  10. // Texas Instruments Incorporated, General Electric Company,
  11. // provides this software "as is" without express or implied warranty.
  12. //
  13. // Created: MBN 04/21/89 -- Initial design and implementation
  14. // Updated: MBN 06/22/89 -- Removed non-destructive methods
  15. // Updated: LGO 08/09/89 -- Inherit from Generic
  16. // Updated: MBN 08/20/89 -- Changed template usage to reflect new syntax
  17. // Updated: MBN 09/11/89 -- Added conditional exception handling and base class
  18. // Updated: LGO 10/05/89 -- Don't re-allocate data in operator= when same size
  19. // Updated: LGO 10/19/89 -- Add extra parameter to varargs constructor
  20. // Updated: MBN 10/19/89 -- Added optional argument to set_compare method
  21. // Updated: LGO 12/08/89 -- Allocate column data in one chunk
  22. // Updated: LGO 12/08/89 -- Clean-up get and put, add const everywhere.
  23. // Updated: LGO 12/19/89 -- Remove the map and reduce methods
  24. // Updated: MBN 02/22/90 -- Changed size arguments from int to unsigned int
  25. // Updated: MJF 06/30/90 -- Added base class name to constructor initializer
  26. // Updated: VDN 02/21/92 -- New lite version
  27. // Updated: VDN 05/05/92 -- Use envelope to avoid unecessary copying
  28. //
  29. // The parameterized Matrix<Type>  class is publicly   derived from the  Matrix
  30. // class and implements two dimensional arithmetic matrices of a user specified
  31. // type.   This is accompilshed by using  the parameterized  type capability of
  32. // C++.  The only constraint placed on the type  is  that it must  overload the
  33. // following operators: +, -,  *,  and /. Thus, it will  be possible to have  a
  34. // Matrix of  type Complex.  The Matrix<Type> class  is static in size, that is
  35. // once a  Matrix<Type> of  a particular  size has been   declared, there is no
  36. // dynamic growth or resize method available.
  37. //
  38. // Each matrix contains  a protected  data section  that has a  Type** slot  that
  39. // points to the  physical memory allocated  for the two  dimensional array. In
  40. // addition, two integers  specify   the number  of  rows  and columns  for the
  41. // matrix.  These values  are provided in the  constructors. A single protected
  42. // slot  contains a pointer  to a compare  function  to   be used  in  equality
  43. // operations. The default function used is the built-in == operator.
  44. //
  45. // Four  different constructors are provided.  The  first constructor takes two
  46. // integer arguments  specifying the  row  and column  size.   Enough memory is
  47. // allocated to hold row*column elements  of type Type.  The second constructor
  48. // takes the  same two  first arguments, but  also accepts  an additional third
  49. // argument that is  a reference to  an  object of  the appropriate  type whose
  50. // value is used as an initial fill value.  The third constructor is similar to
  51. // the third, except that it accpets a variable number of initialization values
  52. // for the Matrix.  If there are  fewer values than elements,  the rest are set
  53. // to zero. Finally, the last constructor takes a single argument consisting of
  54. // a reference to a Matrix and duplicates its size and element values.
  55. //
  56. // Methods   are  provided   for destructive   scalar   and Matrix    addition,
  57. // multiplication, check for equality  and inequality, fill, reduce, and access
  58. // and set individual elements.  Finally, both  the  input and output operators
  59. // are overloaded to allow for fomatted input and output of matrix elements.
  60.  
  61. #ifndef MATRIXH                    // If no Matrix class,
  62. #define MATRIXH                    // define it
  63.  
  64. #ifndef STDARGH
  65. #if defined(DOS)
  66. extern "C" {
  67. #include <stdarg.h>                // for variable arglists
  68. }
  69. #else
  70. #include <stdarg.h>                // for variable arglists
  71. #endif
  72. #define STDARGH
  73. #endif
  74.  
  75. #ifndef BASE_MATRIXH                // If no base class definition
  76. #include <cool/Base_Matrix.h>            // include it
  77. #endif    
  78.  
  79. template<class Type> CoolMatrix {
  80.   typedef Boolean (*Type##_CoolMatrix_Compare) (const Type&, const Type&); 
  81.   class CoolMatrix<Type>E;            // forward declaration for envelope
  82. }
  83.  
  84. template<class Type>
  85. class CoolMatrix<Type> : public CoolMatrix {
  86. //  friend class CoolVec<Type>;                 // not feasible with COOLcpp
  87. public:
  88.   CoolMatrix<Type> (unsigned int r=1, unsigned int c=1); // m (r,c);
  89.   CoolMatrix<Type> (unsigned int r, unsigned int c, const Type& v0); // m(r,c,init);
  90.   CoolMatrix<Type> (unsigned int r, unsigned int c, int n, 
  91.             Type v00, ...); 
  92.   CoolMatrix<Type> (unsigned int r, unsigned int c, // from a block of data
  93.             const Type* data_block);        // stored row-wise.
  94.  
  95.   CoolMatrix<Type> (const CoolMatrix<Type>&);    // m1 = m2;
  96.   ~CoolMatrix<Type>();                // Destructor
  97.   
  98.   inline void put (unsigned int r, unsigned int, Type&); // Assign value
  99.   inline Type& get (unsigned int r, unsigned int);       // Get value
  100.   void fill (const Type&);                   // Set elements to value
  101.   
  102.   inline Type& operator() (unsigned int r, unsigned int c=0); // Access wo checks
  103.   
  104.   CoolMatrix<Type>& operator= (const Type&);    // Assignment: m = 2;
  105.   CoolMatrix<Type>& operator= (const CoolMatrix<Type>&); // Assignment: m = n;
  106.   inline CoolMatrix<Type>& operator= (CoolMatrix<Type>E&); 
  107.   
  108.   Boolean operator== (const CoolMatrix<Type>&) const; // CoolMatrix equality test
  109.   inline Boolean operator!= (const CoolMatrix<Type>&) const; // inequality test
  110.   void set_compare (Type##_CoolMatrix_Compare = NULL);         // Compare function
  111.   
  112.   inline friend ostream& operator<< (ostream&, const CoolMatrix<Type>*);
  113.   friend ostream& operator<< (ostream&, const CoolMatrix<Type>&);
  114.   
  115.   CoolMatrix<Type>& operator+= (const Type&);    // binary operation and assignment
  116.   CoolMatrix<Type>& operator*= (const Type&);    // Mutate matrix data
  117.   CoolMatrix<Type>& operator/= (const Type&);
  118.   inline CoolMatrix<Type>& operator-= (const Type&);    
  119.   
  120.   CoolMatrix<Type>& operator+= (const CoolMatrix<Type>&);
  121.   CoolMatrix<Type>& operator-= (const CoolMatrix<Type>&);
  122.   inline CoolMatrix<Type>& operator*= (const CoolMatrix<Type>&);
  123.   
  124.   CoolMatrix<Type>E operator- () const;        // negation and 
  125.   CoolMatrix<Type>E operator+ (const Type&) const; // all binary operations 
  126.   CoolMatrix<Type>E operator* (const Type&) const; // return by values.
  127.   CoolMatrix<Type>E operator/ (const Type&) const;
  128.   
  129.   inline CoolMatrix<Type>E operator- (const Type&) const; 
  130.   inline friend CoolMatrix<Type>E operator+ (const Type&, const CoolMatrix<Type>&);
  131.   inline friend CoolMatrix<Type>E operator- (const Type&, const CoolMatrix<Type>&);
  132.   inline friend CoolMatrix<Type>E operator* (const Type&, const CoolMatrix<Type>&);
  133.   
  134. // Fewer unnecessary copying with CoolEnvelope
  135. //   friend CoolMatrix<Type>E operator+ (const CoolMatrix<Type>&, 
  136. //                       const CoolMatrix<Type>&);
  137. //   friend CoolMatrix<Type>E operator- (const CoolMatrix<Type>&, 
  138. //                       const CoolMatrix<Type>&);
  139.   friend CoolMatrix<Type>E operator* (const CoolMatrix<Type>&, 
  140.                       const CoolMatrix<Type>&);
  141.   
  142.   ////--------------------------- Additions ------------------------------------
  143.   
  144.   CoolMatrix<Type>E transpose () const;        // transpose row/column
  145.   
  146.   CoolMatrix<Type>E abs () const;        // absolute of all elements
  147.   CoolMatrix<Type>E sign () const;
  148.   CoolMatrix<Type>E extract (unsigned int rows, unsigned int cols, // get submatrix
  149.                 unsigned int top=0, unsigned int left=0) const;
  150.   CoolMatrix<Type>& update (const CoolMatrix<Type>&, // update submatrix
  151.                 unsigned int top=0, unsigned int left=0);         
  152.   
  153.   friend CoolMatrix<Type>E element_product (const CoolMatrix<Type>&, // a[ij]*b[ij]
  154.                        const CoolMatrix<Type>&);
  155.   friend CoolMatrix<Type>E element_quotient (const CoolMatrix<Type>&, // a[ij]/b[ij]
  156.                         const CoolMatrix<Type>&);
  157.   Type determinant() const;            // determinant of square matrix
  158.  
  159.   
  160.   ////--------------------------- Vector ---------------------------------------
  161.   
  162.   inline Type& x ();                // using a 2d matrix
  163.   inline Type& y ();                // to represent a 1d vector
  164.   inline Type& z ();                // is less efficient 
  165.   inline Type& t ();                // in time and space
  166.   
  167.   friend Type dot_product (const CoolMatrix<Type>&, // dot-product of n-dim vectors
  168.                const CoolMatrix<Type>&); 
  169.   friend Type cross_2d (const CoolMatrix<Type>&, // cross-product of 2d-vectors
  170.             const CoolMatrix<Type>&);
  171.   friend CoolMatrix<Type>E cross_3d (const CoolMatrix<Type>&, // cross-product 
  172.                     const CoolMatrix<Type>&); // of 3d-vectors 
  173.  
  174.   inline const Type* data_block ();        // block of data, row-major order.
  175.  
  176. protected:
  177.   Type** data;                    // Pointer to the CoolMatrix 
  178.   static Type##_CoolMatrix_Compare compare_s;    // Pointer operator== function
  179.   friend Boolean Type##_CoolMatrix_is_data_equal (const Type&, const Type&);
  180. };
  181.  
  182.  
  183. // Avoid deep copy on return by value, add and subtract in place.
  184.  
  185. template<class Type> CoolMatrix {
  186. typedef int ________int;            // Coolcpp hack, get rid off it soon
  187.  
  188. #define ENVELOPE_PLUS                // the operators +=, -=, 
  189. #define ENVELOPE_MINUS                // can be done in place
  190.  
  191. #define CoolLetter CoolMatrix<Type>
  192. #define CoolEnvelope CoolMatrix_##Type##E    // for Coolcpp parsing
  193.  
  194. #include <cool/Envelope.h>            // Include envelope macros
  195.  
  196. #undef CoolLetter
  197. #undef CoolEnvelope
  198.  
  199. #undef ENVELOPE_PLUS
  200. #undef ENVELOPE_MINUS
  201. }
  202.  
  203. // get -- Get the element at specified index and return value
  204. // Input: this*, row, column
  205. // Output: Element value
  206.  
  207. template<class Type> 
  208. inline Type& CoolMatrix<Type>::get (unsigned int row, unsigned int column) {
  209. #if ERROR_CHECKING
  210.   if (row >= this->num_rows)            // If invalid size specified
  211.     this->row_index_error ("get", #Type, row);    // Raise exception
  212.   if (column >= this->num_cols)            // If invalid size specified
  213.     this->col_index_error ("get", #Type, column); // Raise exception
  214. #endif
  215.   return this->data[row][column];
  216. }
  217.  
  218. // put -- Put the element value at specified index
  219. // Input: *this, row, column, value
  220. // Output: Element value
  221.  
  222. template<class Type> 
  223. inline void CoolMatrix<Type>::put (unsigned int row, unsigned int column, Type& value) {
  224. #if ERROR_CHECKING
  225.   if (row >= this->num_rows)            // If invalid size specified
  226.     this->row_index_error ("put", #Type, row);    // Raise exception
  227.   if (column >= this->num_cols)            // If invalid size specified
  228.     this->col_index_error ("put", #Type, column); // Raise exception
  229. #endif
  230.   this->data[row][column] = value;        // Assign data value
  231. }
  232.  
  233. // operator() -- Overload () to get the element at specified index
  234. //               and return by reference
  235. // Input: this*, row, column
  236. // Output: Element value
  237.  
  238. template<class Type> 
  239. inline Type& CoolMatrix<Type>::operator() (unsigned int row, unsigned int column) {
  240.   return this->data[row][column];        // fast access without checks.
  241. }
  242.  
  243.  
  244. // operator=  -- Assignment from an envelope back to real matrix
  245. // Input:     envelope reference
  246. // Output:    matrix reference with contents in envelope being swapped over
  247.  
  248. template<class Type>
  249. inline CoolMatrix<Type>& CoolMatrix<Type>::operator= (CoolMatrix<Type>E& env){
  250.   env.shallow_swap((CoolMatrix<Type>E*)this, &env); // same physical layout
  251.   return *this;
  252. }
  253.  
  254. // operator<< -- Overload the output operator to print a CoolMatrix
  255. // Input:        ostream reference, CoolMatrix pointer
  256. // Output:       ostream reference
  257.  
  258. template<class Type> CoolMatrix {
  259. inline ostream& operator<< (ostream& os, const CoolMatrix<Type>* m) {
  260.   if (m) os << *m;
  261.   return os;
  262. }}
  263.  
  264.  
  265. // operator!= -- Perform not equal comparison test
  266. // Input:        this*, matrix reference
  267. // Output:       TRUE/FALSE
  268.  
  269. template<class Type> 
  270. inline Boolean CoolMatrix<Type>::operator!= (const CoolMatrix<Type>& m) const {
  271.   return (!operator== (m));
  272. }
  273.  
  274. // operator-= -- Destructive matrix subtraction of a scalar.
  275. // Input:        this*, scalar value
  276. // Output:       New matrix reference
  277.  
  278. template<class Type> 
  279. inline CoolMatrix<Type>& CoolMatrix<Type>::operator-= (const Type& value) {
  280.   return *this += (- value);
  281. }
  282.  
  283.  
  284. template<class Type> CoolMatrix {
  285. inline CoolMatrix<Type>E operator+ (const Type& value,
  286.                     const CoolMatrix<Type>& m) {
  287.   return m + value;
  288. }}
  289.  
  290. // operator- -- Non-destructive matrix substraction of a scalar.
  291. // Input:       this*, scalar value
  292. // Output:      New matrix 
  293.  
  294. template<class Type> 
  295. inline CoolMatrix<Type>E CoolMatrix<Type>::operator-(const Type& value) const {
  296.   return (*this) + (- value);
  297. }
  298.  
  299. template<class Type> CoolMatrix {
  300. inline CoolMatrix<Type>E operator- (const Type& value,
  301.                     const CoolMatrix<Type>& m) {
  302.   return (- m) + value;
  303. }}
  304.  
  305.  
  306. template<class Type> CoolMatrix {
  307. inline CoolMatrix<Type>E operator* (const Type& value,
  308.                     const CoolMatrix<Type>& m) {
  309.   return m * value;
  310. }}
  311.  
  312. template<class Type>
  313. inline CoolMatrix<Type>& CoolMatrix<Type>::operator*= (const CoolMatrix<Type>&m) {
  314.   *this = (*this) * m;                // multiply, then shallow swap
  315.   return *this;
  316. }
  317.  
  318. ////--------------------------  Vector ----------------------------------
  319. //// use a column matrix to represent 1d vector
  320.  
  321. template<class Type>                
  322. inline Type& CoolMatrix<Type>::x(){
  323.   return data[0][0];
  324. }        
  325.  
  326. template<class Type>
  327. inline Type& CoolMatrix<Type>::y() {
  328.   return data[1][0];
  329. }
  330.  
  331. template<class Type>
  332. inline Type& CoolMatrix<Type>::z() {
  333.   return data[2][0];
  334. }        
  335.  
  336. template<class Type>
  337. inline Type& CoolMatrix<Type>::t() {
  338.   return data[3][0];
  339. }    
  340.  
  341.  
  342. // template<class Type>                // use a row matrix to
  343. // inline Type& CoolMatrix<Type>::x() {            // represent 1d vector
  344. //   return data[0][0];
  345. // }        
  346. // 
  347. // template<class Type>
  348. // inline Type& CoolMatrix<Type>::y() {
  349. //   return data[0][1];
  350. // }
  351. // 
  352. // template<class Type>
  353. // inline Type& CoolMatrix<Type>::z() {
  354. //   return data[0][2];
  355. // }        
  356. // 
  357. // template<class Type>
  358. // inline Type& CoolMatrix<Type>::t() {
  359. //   return data[0][3];
  360. // }    
  361.  
  362. // data_block -- Provide access to the contiguous block storing 
  363. //               the elements in the matrix row-wise.
  364. //               Use this only to cast matrix contents,
  365. //               to C array like: Type [rows][columns].
  366.  
  367. template<class Type>
  368. inline const Type* CoolMatrix<Type>::data_block () {
  369.   return data[0];                // start of array of data
  370. }
  371.  
  372. #endif                        // End of MATRIXH
  373.  
  374.  
  375.